﻿using System;
using System.Collections.Generic;
using SocketControl.Protocol.Http.Expand;
using SocketControl.Protocol.Http.Model.General;
using SocketControl.Protocol.Http.Model;

namespace SocketControl.Protocol.Http.General
{

    public class GeneralHead
    {
        #region define fields
        private string cache_control;
        private string connection;
        private string date;
        private string pragma;
        private string transfer_encoding;
        private string via;
        private string upgrade;
        private string content_length;
        private string content_type;
        private string content_encoding;

        #endregion

        #region Serialize
        Func<string, IList<Model.Item>> CacheControl = delegate (string param)
        {
            return param.Analysis();

        };
        Func<string, string> Connection = delegate (string param) { return param; };
        Func<string, DateTime> Date = delegate (string param) { return !param.IsNull() ? DateTime.Parse(param) : default(DateTime); };
        Func<string, string> Pragma = delegate (string param) { return param; };
        Func<string, string> TransfeEncoding = delegate (string param) { return param; };
        Func<string, string> Via = delegate (string param) { return param; };
        Func<string, string> Upgrade = delegate (string param) { return param; };
        Func<string, string> ContentLength = delegate (string param) { return param; };
        Func<string, string> ContentType = delegate (string param) { return param; };
        Func<string, string> ContentEncoding = delegate (string param) { return param; };
        #endregion

        #region Deserialize
        Func<GeneralHeadModel, string> DeCacheControl = delegate (GeneralHeadModel param) { return param.Cache_Control.DeserializeToMessage(); };
        Func<GeneralHeadModel, string> DeConnection = delegate (GeneralHeadModel param) { return param.Connection; };
        Func<GeneralHeadModel, string> DeDate = delegate (GeneralHeadModel param) { return param.Date.ToUniversalTime().ToString(); };
        Func<GeneralHeadModel, string> DePragma = delegate (GeneralHeadModel param) { return param.Pragma; };
        Func<GeneralHeadModel, string> DeTransfeEncoding = delegate (GeneralHeadModel param) { return param.Transfer_Encoding; };
        Func<GeneralHeadModel, string> DeVia = delegate (GeneralHeadModel param) { return param.Via; };
        Func<GeneralHeadModel, string> DeUpgrade = delegate (GeneralHeadModel param) { return param.Upgrade; };
        Func<GeneralHeadModel, string> DeContentLength = delegate (GeneralHeadModel param) { return param.Content_Length; };
        Func<GeneralHeadModel, string> DeContentType = delegate (GeneralHeadModel param) { return param.Content_Type; };
        Func<GeneralHeadModel, string> DeContentEncoding = delegate (GeneralHeadModel param) { return param.Content_Encoding; };

        #endregion


        #region Method

        internal string GetMessageString(GeneralHeadModel args = null)
        {
            if (args != null)
            {
                this.Deserialize(args);
            }
            string result = string.Empty;
            if (!cache_control.IsNull()) { result.JoinAfterWithCRLF("Cache-Control:" + this.cache_control, out result); }
            if (!connection.IsNull()) { result.JoinAfterWithCRLF("Connection:" + this.connection, out result); }
            if (!date.IsNull()) { result.JoinAfterWithCRLF("Date:" + this.date, out result); }
            if (!pragma.IsNull()) { result.JoinAfterWithCRLF("Pragma:" + this.pragma, out result); }
            if (!transfer_encoding.IsNull()) { result.JoinAfterWithCRLF("Transfer-Encoding:" + this.transfer_encoding, out result); }
            if (!via.IsNull()) { result.JoinAfterWithCRLF("Via:" + this.via, out result); }
            if (!upgrade.IsNull()) { result.JoinAfterWithCRLF("Upgrade:" + this.upgrade, out result); }
            if (!content_length.IsNull()) { result.JoinAfterWithCRLF("Content-Length:" + this.content_length, out result); }
            if (!content_type.IsNull()) { result.JoinAfterWithCRLF("Content-Type:" + this.content_type, out result); }
            if (!content_encoding.IsNull()) { result.JoinAfterWithCRLF("Content-Encoding:" + this.content_encoding, out result); }
            return result;
        }

        internal Model.GeneralHeadModel GetInstance()
        {
            return new Model.GeneralHeadModel()
            {
                Cache_Control = CacheControl(this.cache_control),
                Connection = Connection(this.connection),
                Date = Date(this.date),
                Pragma = Pragma(this.pragma),
                Transfer_Encoding = TransfeEncoding(this.transfer_encoding),
                Via = Via(this.via),
                Upgrade = Upgrade(this.upgrade),
                Content_Length = ContentLength(this.content_length),
                Content_Type = ContentType(this.content_type),
                Content_Encoding = ContentEncoding(this.content_encoding)
            };
        }
        internal Model.GeneralHeadModel GetInstance(string args)
        {
            this.AnalysisMessage(args);
            return this.GetInstance();
        }



        private void Deserialize(GeneralHeadModel args)
        {
            this.cache_control = DeCacheControl(args);
            this.connection = DeConnection(args);
            this.date = DeDate(args);
            this.pragma = DePragma(args);
            this.transfer_encoding = DeTransfeEncoding(args);
            this.via = DeVia(args);
            this.upgrade = DeUpgrade(args);
            this.content_length = DeContentLength(args);
            this.content_type = DeContentType(args);
            this.content_encoding = DeContentEncoding(args);
        }

        private void AnalysisMessage(string args)
        {
            int line = 0;
            foreach (string o in args.ReadLine())
            {
                if (line > 0)
                {
                    string[] param = AnalysisLine(o);
                    switch (param[0].ToLower())
                    {
                        case "cache-control": { this.cache_control = param[1]; break; }
                        case "connection": { this.connection = param[1]; break; }
                        case "date": { this.date = param[1]; break; }
                        case "pragma": { this.pragma = param[1]; break; }
                        case "transfer-encoding": { this.transfer_encoding = param[1]; break; }
                        case "via": { this.via = param[1]; break; }
                        case "upgrade": { this.upgrade = param[1]; break; }
                        case "content-length": { this.content_length = param[1]; break; }
                        case "content-type": { this.content_type = param[1]; break; }
                        case "content-encoding": { this.content_encoding = param[1]; break; }
                    }
                }
                ++line;
            }
        }

        internal string[] AnalysisLine(string args)
        {
            string[] result = new string[2];
            int offset = args.IndexOf(':');
            if (offset > 0)
            {
                result[0] = args.Substring(0, offset).ToLower();
                result[1] = args.Substring(offset + 1, args.Length - offset - 1);
            }
            return result;
        }
        #endregion
    }
}
